/**
 * 
 */
package it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.world;

import it.unical.canonaco.rende.igpe.game.cbv.datastructure.RBTree;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.pawn.GenericPawn;

/**
 * @author Massimo Canonaco
 * @author Fabio Rende
 */
public class Chessboard {
	
	/** */
	private Field[][] chessboard;
	
	/** */
	private RBTree<SpawnCoordinate> spawnCells;
	
	/** */
	public Chessboard(final int chess, int size)
	{
		spawnCells = new RBTree<>();
		chessboard = new Field[size][size];
		
		for(int rowIndex = 0; rowIndex < size; rowIndex++)
		{
			for(int columnIndex = 0; columnIndex < size; columnIndex++)
			{
				chessboard[rowIndex][columnIndex] = new Field();
			}
		}
	}
	
	/** */
	public void addSpawnCells(final int row, final int column)
	{
		if(validCoordinate(row, column)	&& !chessboard[row][column].spawnable)
		{
			SpawnCoordinate cell = new SpawnCoordinate();
			cell.row = String.valueOf(row);
			cell.column = String.valueOf(column);
			spawnCells.add(cell);
			chessboard[row][column].spawnable = true;
		}
	}
	
	/**@return Return the size of the chessboard. */
	public int getSize()
	{
		return chessboard.length;
	}
	
	/**If the coordinates are valid and there's a spawn cell on them, that cell is set as not spawnable.
	 * @param row 			is the row value coordinate.
	 * @param column 		is the column value coordinate. */
	public void removeSpawnCells(final int row, final int column)
	{
		if(validCoordinate(row, column) && chessboard[row][column].spawnable)
		{
			SpawnCoordinate cell = new SpawnCoordinate();
			cell.row = String.valueOf(row);
			cell.column = String.valueOf(column);
			spawnCells.delete(cell);
		}
	}
	
	/** */
	public void setWalkable(final int row, final int column, final boolean value)
	{
		if(validCoordinate(row, column))
		{
			chessboard[row][column].walkable = value;
		}
	}
	
	/** */
	public void addPawn(final int row, final int column, final GenericPawn pawn)
	{
		if(validCoordinate(row, column))
		{
			chessboard[row][column].pawn = pawn;
			System.out.println("aggiungiamo in "+row+" "+column);
		}
		System.out.println(this);
	}
	
	/** */
	public GenericPawn getPawn(final int row, final int column)
	{
		if(validCoordinate(row,column))
		{
			return chessboard[row][column].pawn;
		}
		
		return null;
	}
	
	/** */
	public void dropPawn(final int row, final int column)
	{
		if(validCoordinate(row,column))
		{
			chessboard[row][column].pawn = null;
		}
	}
	
	/**Checks if the passed pawn is on the passed cell coordinates.
	 * @param row 			is the row value coordinate.
	 * @param column 		is the column value coordinate. 
	 * @param pawn			is the pawn to check.
	 * @return True, the coordinate are valid and the pawn is on that cell; false otherwise. */
	public boolean isPawnOn(final int row, final int column, final GenericPawn pawn)
	{
		return validCoordinate(row, column) && chessboard[row][column].pawn != null && chessboard[row][column].pawn == pawn;
	}
	
	/**Checks if the passed cell coordinates are a free cell.
	 * @param row 			is the row value coordinate.
	 * @param column 		is the column value coordinate. 
	 * @return True, the coordinate are valid and the cell is free; false otherwise. */
	public boolean isFree(final int row, final int column)
	{
		return validCoordinate(row, column) && chessboard[row][column].pawn == null;
	}
	
	/** */
	public boolean isWalkable(final int row, final int column)
	{
		return validCoordinate(row, column) == true && chessboard[row][column].walkable;
	}
	
	public boolean isSpawnable(final int row, final int column)
	{
		return validCoordinate(row, column) == true && chessboard[row][column].spawnable;
	}
	
	private boolean validCoordinate(final int row, final int column)
	{
		return (row >= 0 && row < chessboard[0].length && column >= 0 && column < chessboard[0].length);
	}
	
	public void setTexture(final int row, final int column, final TextureInfoBean texture)
	{
		if(validCoordinate(row, column))
		{
			chessboard[row][column].texture = texture;
		}
	}
	
	public TextureInfoBean getTexture(final int row, final int column)
	{
		if(validCoordinate(row, column))
			return chessboard[row][column].texture;
		return null;
	}
	
	/**
	 * @return the spawnCells
	 */
	public RBTree<SpawnCoordinate> getSpawnCells() {
		return spawnCells;
	}
	
//	/** */
//	private static class SpawnCoordinate
//	{
//		private String row;
//		private String column;
//		
//		@Override
//		public int hashCode() {
//			return Integer.parseInt(row+column);
//		}
//	}
}
